package ve.usb.crm;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;

import ve.usb.cohesion.runtime.CohesionAction;

import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;
import ve.usb.cohesion.runtime.HibernateUtil;
import ve.usb.crm.hibernate.*;

import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import java.util.Date;
import ve.usb.cohesion.runtime.LocalDate;
import ve.usb.cohesion.runtime.Pair;

/**
 * 
 */
public class AccionesCliente extends CohesionAction {

    /**
     * Called by Struts for the execution of action APreClientes.
     * 
     * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @return The Struts name of the following step.
     * @throws java.lang.Exception For untreated exceptions. 
     * These exceptios will normally be treated with 
     * the default exception action.
     */
    public ActionForward APreClientes(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        //Salidas
        final String[] SALIDAS = {"VClientes", "APreClientes",};
        final int SALIDA_0 = 0;
        final int SALIDA_1 = 1;

        int salida = SALIDA_0;
//Checking for actors administrador, empleado
        if (!CohesionActor.checkActor(request, 5)) {
            return mapping.findForward(CohesionActor.SALIDA_ACTOR);
        }
        Session s = HibernateUtil.getCurrentSession();
        Transaction tr = s.beginTransaction();
        try {
//Saco la lista de todos los contactos

            List<Contacto> list = new ArrayList<Contacto>();
            if (CohesionActor.checkActor(request, CohesionActor.ACTOR_administrador)) {
                list = (List<Contacto>) s.createQuery("from Contacto where esCliente = :bool and esActivo = true").setBoolean("bool", true).list();
            } else if (CohesionActor.checkActor(request, CohesionActor.ACTOR_empleado)) {
                Personal usuario = (Personal) request.getSession().getAttribute("Usuario");
                list = (List<Contacto>) s.createQuery("from Contacto where"
                        + " esCLiente = :bool and persona = :usuario and esActivo = true").setLong("usuario", usuario.getIdPersonal()).setBoolean("bool", true).list();
            }

            //Obtengo el valor cuenta de cada uno de los contactos
            for (Iterator<Contacto> it = list.iterator(); it.hasNext();) {
                Contacto contacto = it.next();
                Hibernate.initialize(contacto.getPersona());
                Hibernate.initialize(contacto.getCuenta());

            }

            //Subo el atributo al request
            request.setAttribute("L_Contacto", list);

            tr.commit();

        } catch (Exception ex) {
            tr.rollback();
            throw ex;
        } finally {
            try {
                s.close();
            } catch (Exception ex2) {
            }
        }
        return mapping.findForward(SALIDAS[salida]);
    }

    /**
     * Called by Struts for the execution of action APreCliente.
     * 
     * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @return The Struts name of the following step.
     * @throws java.lang.Exception For untreated exceptions. 
     * These exceptios will normally be treated with 
     * the default exception action.
     */
    public ActionForward APreCliente(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        //Salidas
        final String[] SALIDAS = {"VCliente", "APreClientes",};
        final int SALIDA_0 = 0;
        final int SALIDA_1 = 1;

        int salida = SALIDA_0;
//Checking for actors empleado, administrador
        if (!CohesionActor.checkActor(request, 5)) {
            return mapping.findForward(CohesionActor.SALIDA_ACTOR);
        }
        Session s = HibernateUtil.getCurrentSession();
        Transaction tr = s.beginTransaction();
        try {

            Long idContacto = (Long) request.getAttribute("idCliente");
            if (idContacto == null) {
                idContacto = lookup_Long(request, "idCliente");
            }

            if (idContacto == null) {
                salida = SALIDA_1;
            } else {
                Contacto contacto = null;
                if (CohesionActor.checkActor(request, CohesionActor.ACTOR_administrador)) {


                    contacto = (Contacto) s.createQuery("from Contacto where "
                            + "idContacto = :idContacto and esCliente = :bool").setBoolean("bool", true).
                            setLong("idContacto", idContacto).uniqueResult();
                } else if (CohesionActor.checkActor(request, CohesionActor.ACTOR_empleado)) {
                    Personal usuario = (Personal) request.getSession().getAttribute("usuario");

                    contacto = (Contacto) s.createQuery("from Contacto where "
                            + "idContacto = :idContacto and esCliente = :bool and persona = :usuario").setBoolean("bool", true).
                            setLong("idContacto", idContacto).
                            setLong("usuario", usuario.getIdPersonal()).uniqueResult();
                } else if (CohesionActor.checkActor(request, CohesionActor.ACTOR_cliente)) {
                    Contacto usuario = (Contacto) request.getSession().getAttribute("usuario");

                    if (idContacto == usuario.getIdContacto() && usuario.getEsCliente()) {
                        contacto = usuario;
                    }
                }
                if (contacto == null) {
                    salida = SALIDA_1;

                } else {

                    Personal responsable = contacto.getPersona();
                    Cuenta cuenta = contacto.getCuenta();

                    Hibernate.initialize(contacto.getTitulo());
                    Hibernate.initialize(responsable);
                    Hibernate.initialize(cuenta);

                    List<Tarea> listaTarea =
                            (List<Tarea>) s.createQuery("from Tarea where"
                            + " contactoRelacionado = :idContacto").setLong("idContacto", contacto.getIdContacto()).list();

                    for (Iterator<Tarea> it = listaTarea.iterator(); it.hasNext();) {
                        Tarea tarea = it.next();
                        Hibernate.initialize(tarea.getPersonal());
                        Hibernate.initialize(tarea.getAsunto());
                        Hibernate.initialize(tarea.getEstado());
                        Hibernate.initialize(tarea.getContactoRelacionado());


                    }

                    List<ContactoPregunta> preguntasContacto = (List<ContactoPregunta>) s.createQuery("from ContactoPregunta where contacto = :idContacto").setLong("idContacto", contacto.getIdContacto()).list();

                    for (Iterator<ContactoPregunta> it = preguntasContacto.iterator(); it.hasNext();) {
                        ContactoPregunta contactoPregunta = it.next();
                        Hibernate.initialize(contactoPregunta.getPregunta());
                        Hibernate.initialize(contactoPregunta.getPregunta().getIdSoporteTecnico());

                    }

                    request.setAttribute("SoporteTecnico", preguntasContacto);

                    request.setAttribute("Cliente", contacto);
                    request.setAttribute("Usuario", responsable);
                    request.setAttribute("Cuenta", cuenta);
                    request.setAttribute("L_Tarea", listaTarea);
                }
            }
            tr.commit();

        } catch (Exception ex) {
            tr.rollback();
            throw ex;
        } finally {
            try {
                s.close();
            } catch (Exception ex2) {
            }
        }
        return mapping.findForward(SALIDAS[salida]);
    }

    /**
     * Called by Struts for the execution of action ACrearCliente.
     * 
     * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @return The Struts name of the following step.
     * @throws java.lang.Exception For untreated exceptions. 
     * These exceptios will normally be treated with 
     * the default exception action.
     */
    public ActionForward ACrearCliente(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        //Salidas
        final String[] SALIDAS = {"VCrearCliente", "APreCliente",};
        final int SALIDA_0 = 0;
        final int SALIDA_1 = 1;

        int salida = SALIDA_0;
//Checking for actors empleado, administrador
        if (!CohesionActor.checkActor(request, 5)) {
            return mapping.findForward(CohesionActor.SALIDA_ACTOR);
        }
        Session s = HibernateUtil.getCurrentSession();
        Transaction tr = s.beginTransaction();
        try {
            FCrearContacto fFCrearContacto = (FCrearContacto) form;
//Inicializo el contacto y la fecha
            Contacto nuevoContacto = new Contacto();
            Date date = new Date();
            boolean hayError = false;

            //Verifico si el usuario es nuevo o viejo para modificarlo
            if (fFCrearContacto.getIdContacto() != 0l) {
                nuevoContacto = (Contacto) s.createQuery("from Contacto where idContacto = :idContacto").setLong("idContacto", fFCrearContacto.getIdContacto()).uniqueResult();
            } else {
                nuevoContacto.setFechaCreacion(date);
            }

            //Verifico que el nombre este
            if (fFCrearContacto.getNombre().compareTo("") == 0) {
                hayError = true;
                request.setAttribute("nombreError", "<span class='ui-icon ui-icon-alert' style='float: left; margin-right: .3em;'></span>Debe colocar un nombre v&aacute;lido");
            }


            //Verifico que el apellido este
            if (fFCrearContacto.getApellido().compareTo("") == 0) {
                hayError = true;
                request.setAttribute("apellidoError", "<span class='ui-icon ui-icon-alert' style='float: left; margin-right: .3em;'></span>Debe colocar un apellido v&aacute;lido");
            }


            //Verifico que alla escogido una cuenta y si no la escogio obliga a que la escoja
            if (fFCrearContacto.getCuenta() != 0l) {
                Cuenta cuenta = (Cuenta) s.createQuery("from Cuenta where idCuenta = :idCuenta").setLong("idCuenta", fFCrearContacto.getCuenta()).uniqueResult();
                nuevoContacto.setCuenta(cuenta);
            }
//            else {
//                hayError = true;
//                request.setAttribute("cuentaError", "<span class='ui-icon ui-icon-alert' style='float: left; margin-right: .3em;'></span>Debe seleccionar una cuenta v&aacute;lida");
//            }

            //Verifico que alla consegui un responsable y si no la escogio obliga a que la escoja
            if (fFCrearContacto.getPersonalContacto() != 0l) {
                Personal responsable = (Personal) s.createQuery("from Personal where idPersonal = :idPersonal").setLong("idPersonal", fFCrearContacto.getPersonalContacto()).uniqueResult();
                nuevoContacto.setPersona(responsable);
            } else {
                hayError = true;
                request.setAttribute("responsableError", "<span class='ui-icon ui-icon-alert' style='float: left; margin-right: .3em;'></span>Debe seleccionar un nombre de responsable v&aacute;lido");
            }


            if (fFCrearContacto.getFechaNacimiento().compareTo("") != 0) {
                DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
                nuevoContacto.setFechaNacimiento(df.parse(fFCrearContacto.getFechaNacimiento()));
            } else {
                hayError = true;
                request.setAttribute("fechaNacimientoError", "<span class='ui-icon ui-icon-alert' style='float: left; margin-right: .3em;'></span>La fecha de nacimiento es un valor requerido.");
            }

            if (hayError) {
                cargarCollection(fFCrearContacto, s);
                salida = SALIDA_0;
            } else {
                //Cargo todos los datos a la clase contacto
                nuevoContacto.setApellido(fFCrearContacto.getApellido());
                nuevoContacto.setNombre(fFCrearContacto.getNombre());
                nuevoContacto.setCorreoE(fFCrearContacto.getCorreoE());
                nuevoContacto.setDireccion(fFCrearContacto.getDireccion());
                nuevoContacto.setEsCliente(true);
                nuevoContacto.setEsActivo(true);
                nuevoContacto.setFechaCreacion(new LocalDate(fFCrearContacto.getFechaNacimiento()));
                nuevoContacto.setLugarNacimiento(fFCrearContacto.getLugarNacimiento());
                nuevoContacto.setTelefonoFax(fFCrearContacto.getTelefonoFax());
                nuevoContacto.setTelefonoHabitacion(fFCrearContacto.getTelefonoHabitacion());
                nuevoContacto.setTelefonoMovil(fFCrearContacto.getTelefonoMovil());
                nuevoContacto.setUltimaModificacion(date);
                if (fFCrearContacto.getTitulo() != 0l) {
                    Categoria titulo = (Categoria) s.createQuery("from Categoria where idCategoria = :idCategoria").setLong("idCategoria", fFCrearContacto.getTitulo()).uniqueResult();
                    nuevoContacto.setTitulo(titulo);
                }
                salida = SALIDA_1;
                if (fFCrearContacto.getIdContacto() == 0) {
                    s.save(nuevoContacto);
                } else {
                    nuevoContacto.setIdContacto(fFCrearContacto.getIdContacto());
                    s.update(nuevoContacto);
                }
                s.flush();
            }



            tr.commit();

        } catch (Exception ex) {
            tr.rollback();
            throw ex;
        } finally {
            try {
                s.close();
            } catch (Exception ex2) {
            }
        }
        return mapping.findForward(SALIDAS[salida]);
    }

    /**
     * Called by Struts for the execution of action APreEditarCliente.
     * 
     * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @return The Struts name of the following step.
     * @throws java.lang.Exception For untreated exceptions. 
     * These exceptios will normally be treated with 
     * the default exception action.
     */
    public ActionForward APreEditarCliente(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        //Salidas
        final String[] SALIDAS = {"VCrearCliente",};
        final int SALIDA_0 = 0;

        int salida = SALIDA_0;
//Checking for actors administrador, empleado
        if (!CohesionActor.checkActor(request, 5)) {
            return mapping.findForward(CohesionActor.SALIDA_ACTOR);
        }
        Session s = HibernateUtil.getCurrentSession();
        Transaction tr = s.beginTransaction();
        try {

            //CODIGO MIO
            Long idCliente = Long.valueOf((String) request.getParameter("idCliente")).longValue();
            Contacto contacto = (Contacto) s.createQuery("from Contacto where idContacto = :idContacto").setLong("idContacto", idCliente).uniqueResult();

            //Creo el formularo y cargo los valores
            FCrearContacto fFCrearcontacto = FCrearContacto.clear(mapping, request);

            fFCrearcontacto.setIdContacto(contacto.getIdContacto());
            fFCrearcontacto.setApellido(contacto.getApellido());
            fFCrearcontacto.setNombre(contacto.getNombre());
            fFCrearcontacto.setCorreoE(contacto.getCorreoE());

            if (contacto.getCuenta() != null) {
                fFCrearcontacto.setCuenta(contacto.getCuenta().getIdCuenta());
            } else {
                fFCrearcontacto.setCuenta(0L);
            }

            fFCrearcontacto.setDireccion(contacto.getDireccion());
            DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
            fFCrearcontacto.setFechaNacimiento(df.format(contacto.getFechaNacimiento()));

            fFCrearcontacto.setLugarNacimiento(contacto.getLugarNacimiento());
            fFCrearcontacto.setPersonalContacto(contacto.getPersona().getIdPersonal());
            fFCrearcontacto.setTelefonoFax(contacto.getTelefonoFax());
            fFCrearcontacto.setTelefonoHabitacion(contacto.getTelefonoHabitacion());
            fFCrearcontacto.setTelefonoMovil(contacto.getTelefonoMovil());


            if (contacto.getTitulo() != null) {
                fFCrearcontacto.setTitulo(contacto.getTitulo().getIdCategoria());
            }
            cargarCollection(fFCrearcontacto, s);

            //TERMINA CODIGO MIO

            tr.commit();

        } catch (Exception ex) {
            tr.rollback();
            throw ex;
        } finally {
            try {
                s.close();
            } catch (Exception ex2) {
            }
        }
        return mapping.findForward(SALIDAS[salida]);
    }

    /**
     * Called by Struts for the execution of action AEliminarCliente.
     * 
     * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @return The Struts name of the following step.
     * @throws java.lang.Exception For untreated exceptions. 
     * These exceptios will normally be treated with 
     * the default exception action.
     */
    public ActionForward AEliminarCliente(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        //Salidas
        final String[] SALIDAS = {"APreClientes",};
        final int SALIDA_0 = 0;

        int salida = SALIDA_0;
        Session s = HibernateUtil.getCurrentSession();
        Transaction tr = s.beginTransaction();
        try {
            //Consigo el id del contacto
            Long idCliente = lookup_Long(request, "idCliente");
            Contacto cliente = (Contacto) s.load(Contacto.class, idCliente);

            List<Tarea> tarea = (List<Tarea>) s.createQuery("from Tarea where contactorelacionado = :resp").setLong("resp", idCliente).list();
            for (Tarea t : tarea) {
                t.setEsActivo(false);
                s.update(t);
                s.flush();
            }

            cliente.setEsActivo(false);
            s.update(cliente);
            s.flush();

            try {
                s.flush();
            } catch (Exception ex1) {
                ex1.printStackTrace();
                //salida = SALIDA_1;
                request.setAttribute("msg", "No se pudo eliminar entidad.");
            }

            tr.commit();

        } catch (Exception ex) {
            tr.rollback();
            throw ex;
        } finally {
            try {
                s.close();
            } catch (Exception ex2) {
            }
        }
        return mapping.findForward(SALIDAS[salida]);
    }

    /**
     * Called by Struts for the execution of action APreCrearCliente.
     * 
     * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @return The Struts name of the following step.
     * @throws java.lang.Exception For untreated exceptions. 
     * These exceptios will normally be treated with 
     * the default exception action.
     */
    public ActionForward APreCrearCliente(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        //Salidas
        final String[] SALIDAS = {"VCrearCliente",};
        final int SALIDA_0 = 0;

        int salida = SALIDA_0;
        Session s = HibernateUtil.getCurrentSession();
        Transaction tr = s.beginTransaction();
        try {

//Genero el formulario
            FCrearContacto fFCrearContacto = FCrearContacto.clear(mapping, request);

            //Trato de obtener el atributo idCuenta y obtengo el atributo usuario actual en la session
            Long idCuenta = lookup_Long(request, "idCuenta");
            Personal usuario = (Personal) request.getSession().getAttribute("Usuario");

            //Verifico si vengo de una cuenta para agregarlo al formulario
            if (idCuenta != null) {
                fFCrearContacto.setCuenta(idCuenta);
            }

            //Verifico si ahi un usuario en la sesion para agregarlo al formulario
            if (usuario != null) {
                fFCrearContacto.setPersonalContacto(usuario.getIdPersonal());
            }
            cargarCollection(fFCrearContacto, s);

            tr.commit();

        } catch (Exception ex) {
            tr.rollback();
            throw ex;
        } finally {
            try {
                s.close();
            } catch (Exception ex2) {
            }
        }
        return mapping.findForward(SALIDAS[salida]);
    }

    private void cargarCollection(FCrearContacto fFCrearContacto, Session s) {

        Long tituloCategoria = (Long) s.createQuery("select idCategoria from Categoria where nombre = 'titulo'").uniqueResult();


        {
            List<Pair> list =
                    (List<Pair>) s.createQuery(
                    "select new ve.usb.cohesion.runtime.Pair(nombre, idPersonal) "
                    + "from Personal").list();
            list.add(0, new Pair("Ninguna", 0));
            fFCrearContacto.setListPersonal(list);
        }

        {
            List<Pair> listTipo =
                    (List<Pair>) s.createQuery(
                    "select new ve.usb.cohesion.runtime.Pair(nombre, idCategoria) "
                    + "from Categoria where tipo= :idCategoria").setLong("idCategoria", tituloCategoria).list();
            listTipo.add(0, new ve.usb.cohesion.runtime.Pair("Ninguna", 0));
            fFCrearContacto.setListTitulo(listTipo);

        }

        {
            List<Pair> list =
                    (List<Pair>) s.createQuery(
                    "select new ve.usb.cohesion.runtime.Pair(nombre, idCuenta) "
                    + "from Cuenta").list();
            list.add(0, new Pair("Ninguna", 0));
            fFCrearContacto.setListCuenta(list);
        }

    }
}
